package com.cw.utils.web;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 *@Author cuitong
 *@Date: 2019/3/18 10:49
 *@Email: cuitong_sl@163.com
 *@Description:  xss 过滤器
 */
public class XSSFilter implements Filter {
    private final Logger logger = LoggerFactory.getLogger(XSSFilter.class);

    private CommonsMultipartResolver multipartResolver;
    private FilterConfig filterConfig;
    /**
     * 不需要xss过滤的页面
     */
    public static String[] whiteListURL = {
            "/jsp/controller.jsp",
            "/actuator/prometheus"
    };

    /**
     * 需要xss过滤的请求，敏感词需求
     */
    public static String[] methodList = {
            "add","save","edit","update","modify","import","insert",
            //个性化方法名(涉及新增、修改操作)
            //退款管理
//            "platformAccept","refundApply","platformApply","originalPay","serviceAccept","platformAudit",
//            "serviceRefundAudit","inOrOutStock",
            //账单管理-》支付说明
             "onLinePay"
    };

    /**
     * 数据响应白名单
     */
    private static final String[] whiteUrl = {"userLogin/index"};
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        this.filterConfig = filterConfig;
        multipartResolver = new CommonsMultipartResolver();
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
                         FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        MultipartHttpServletRequest multiReq;
        String enctype = httpRequest.getContentType();
        //过滤路径
        //获取URL，不带工程名的url
        String requestURI = httpRequest.getRequestURI();
        String contextPath = httpRequest.getContextPath();
        String urlWithOutContextPath = requestURI.substring(contextPath.length()).toLowerCase();
        //判断URL是否在白名单请求内，例如登录回调
        boolean inwhiteListURL = false;
        for(String whiteURL:whiteListURL){
            if(urlWithOutContextPath.contains(whiteURL.toLowerCase())){
                inwhiteListURL = true;
                break;
            }
        }

        //判断请求是否是需要拦截的，敏感词需求。最开始的时候怕影响范围大，特意加的。
        boolean inMethodList = false;
        for(String method:methodList){
            if(urlWithOutContextPath.contains(method.toLowerCase())){
                inMethodList = true;
                break;
            }
        }
        //这里可以添加过滤路径白名单
        if (inwhiteListURL){
            chain.doFilter(request, response);
        }else {
            //if(inMethodList){
                if (StringUtils.isNotBlank(enctype) && enctype.contains("multipart/form-data")) {
                    multiReq = multipartResolver.resolveMultipart(httpRequest);
                    // 将转化后的 request 放入过滤链中
                    request = multiReq;
                    chain.doFilter(new XssHttpServletRequestWrapper((HttpServletRequest) request,(HttpServletResponse) response), response);
                    //chain.doFilter(new XssHttpServletRequestWrapper2((HttpServletRequest) request), response);
                }else{
                    //chain.doFilter(new XssHttpServletRequestWrapper2((HttpServletRequest) request), response);
                    chain.doFilter(new XssHttpServletRequestWrapper((HttpServletRequest) request,(HttpServletResponse) response), response);
                }
//            }else{
//                chain.doFilter(request, response);
//            }
        }
    }

    @Override
    public void destroy() {
        this.filterConfig= null;
    }
}
